package ru.spb.osll.myfit.server.execute;

import static org.junit.Assert.assertEquals;

import java.io.ByteArrayInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import java.util.Vector;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.easymock.EasyMock;
import org.easymock.EasyMockSupport;
import org.junit.Before;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import ru.spb.osll.myfit.common.Page;
import ru.spb.osll.myfit.common.Table;
import ru.spb.osll.myfit.common.TableCell;
import ru.spb.osll.myfit.server.handler.ContentHandler;
import ru.spb.osll.myfit.server.handler.PageLoader;
import ru.spb.osll.myfit.server.parser.Constants;
import ru.spb.osll.myfit.util.CollectionUtils;

public class XmlPageElementReaderTest extends EasyMockSupport {

	private static String TEST_RESULTS_XML = new String("<?xml version=\"1.0\"?><root><table border=\"1\" cellspacing=\"0\">\n"
                                                          + "      <tr>\n"
                                                          + "        <td>Import</td>\n"
                                                          + "      </tr>\n"
                                                          + "      <tr>\n"
                                                          + "        <td>ru.spb.osll.myfit.examples</td>\n"
                                                          + "      </tr>\n"
                                                          + "    </table>\n"
                                                          + "    <br/><table border=\"1\" cellspacing=\"0\">\n"
                                                          + "      <tr>\n"
                                                          + "        <td colspan=\"7\">with cubetools</td>\n"
                                                          + "      </tr>\n"
                                                          + "      <tr>\n"
                                                          + "        <td class=\"pass\">write</td>\n"
                                                          + "        <td>1000000</td>\n" 
                                                          + "        <td class=\"pass\">files of size</td>\n"
                                                          + "        <td>10KB</td>\n"
                                                          + "        <td class=\"pass\">using</td>\n"
                                                          + "        <td>80</td>\n"
                                                          + "        <td class=\"pass\">threads</td>\n"
                                                          + "      </tr>\n"
                                                          + "    </table></root>");
	private static String TEST_RESULTS_XML_FOR_PARSE = new String("<table border=\"1\" cellspacing=\"0\">\n"
                                                                    + "      <tr>\n"
                                                                    + "       <td>Import</td>\n"
                                                                    + "      </tr>\n"
                                                                    + "      <tr>\n"
                                                                    + "        <td>ru.spb.osll.myfit.examples</td>\n"
                                                                    + "      </tr>\n"
                                                                    + "    </table>\n"
                                                                    + "    <br/><table border=\"1\" cellspacing=\"0\">\n"
                                                                    + "      <tr>\n"
                                                                    + "        <td colspan=\"7\">with cubetools</td>\n"
                                                                    + "      </tr>\n"
                                                                    + "      <tr>\n"
                                                                    + "        <td class=\"pass\">write</td>\n"
                                                                    + "        <td>1000000</td>\n"
                                                                    + "        <td class=\"pass\">files of size</td>\n"
                                                                    + "        <td>10KB</td>\n"
                                                                    + "        <td class=\"pass\">using</td>\n"
                                                                    + "        <td>80</td>\n"
                                                                    + "        <td class=\"pass\">threads</td>\n"
                                                                    + "      </tr>\n"
                                                                    + "    </table>");

	private Page page = new Page();
	private PageLoader loader;
	private ContentHandler m_handler;
	private NodeList nlTables;

	@Before
	public void prepareTestData() throws Exception {
		loader = createMockBuilder(PageLoader.class)
				.addMockedMethod("readPageFile", String.class,String.class).createMock();
		String root = "FitNesseRoot";
		m_handler = new ContentHandler(root, loader);

		List<String> SimpleLoadList = CollectionUtils.list("|Import|",
				"|ru.spb.osll.myfit.examples|", Constants.LINE_SEPARATOR,

				"|with cubetools|",
				"|write|1000000|files of size|0|using|80|threads|",
				Constants.LINE_SEPARATOR);

		String name = "SimPlePage";
		EasyMock.expect(loader.readPageFile(root, name)).andReturn(SimpleLoadList);
		EasyMock.expect(loader.readPageFile(root, ".SetUp")).andThrow(
				new FileNotFoundException(""));
		EasyMock.expect(loader.readPageFile(root, ".TearDown")).andThrow(
				new FileNotFoundException(""));
		replayAll();
		page = m_handler.loadPage(name);
		verifyAll();

		InputSource in = new InputSource(new ByteArrayInputStream(
				TEST_RESULTS_XML.getBytes()));
		DocumentBuilderFactory dfactory = DocumentBuilderFactory.newInstance();
		dfactory.setNamespaceAware(true);
		Document doc = dfactory.newDocumentBuilder().parse(in);
		nlTables = (NodeList) doc.getDocumentElement().getChildNodes();
	}

	@Test
	public void testParse() throws IOException, SAXException,
			ParserConfigurationException {


		Page resultTestPage = XmlPageElementReader.parse(TEST_RESULTS_XML_FOR_PARSE, page);

		int pageCountExpected = page.countPageElements();
		assertEquals(pageCountExpected, resultTestPage.countPageElements());
		for (int i = 0; i < pageCountExpected; i++) {
			assertEquals(page.getElement(i).getType(), resultTestPage
					.getElement(i).getType());
		}
	}

	@Test
	public void testGetTableHeader() {
		assertEquals("with cubetools", XmlPageElementReader
				.getTableHeader((Node) nlTables.item(3)));
	}

	@Test
	public void testProcessTable() {
		Table testTable = XmlPageElementReader.processTable((Node) nlTables
				.item(3));

		Vector<Vector<TableCell>> rows = testTable.getData();
		assertEquals(2, rows.size());

		Vector<TableCell> cells1 = rows.get(0);
		assertEquals(1, cells1.size());
		assertEquals("with cubetools", cells1.get(0).getText());

		Vector<TableCell> cells2 = rows.get(1);
		assertEquals(7, cells2.size());
		assertEquals("write", cells2.get(0).getText());
		assertEquals("1000000", cells2.get(1).getText());
		assertEquals("files of size", cells2.get(2).getText());
		assertEquals("10KB", cells2.get(3).getText());
		assertEquals("using", cells2.get(4).getText());
		assertEquals("80", cells2.get(5).getText());
		assertEquals("threads", cells2.get(6).getText());

	}

	@Test
	public void testProcessRow() {
		Node nodeTable = nlTables.item(3);
		nodeTable.getChildNodes().item(1);

		Vector<TableCell> rowHeader = XmlPageElementReader.processRow(nodeTable
				.getChildNodes().item(1));
		assertEquals(1, rowHeader.size());
		assertEquals("with cubetools", rowHeader.get(0).getText());

		Vector<TableCell> rowExp = XmlPageElementReader.processRow(nodeTable
				.getChildNodes().item(3));
		assertEquals(7, rowExp.size());
		assertEquals("write", rowExp.get(0).getText());
		assertEquals("1000000", rowExp.get(1).getText());
		assertEquals("files of size", rowExp.get(2).getText());
		assertEquals("10KB", rowExp.get(3).getText());
		assertEquals("using", rowExp.get(4).getText());
		assertEquals("80", rowExp.get(5).getText());
		assertEquals("threads", rowExp.get(6).getText());
	}

}
